/**
 * 
 */
package com.tomagency.cyberlab.server.config;

import java.net.URL;
import java.util.Iterator;
import java.util.Properties;
import java.util.TreeSet;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Scopes;
import com.google.inject.Singleton;
import com.google.inject.Stage;
import com.google.inject.servlet.ServletModule;
import com.google.web.bindery.requestfactory.server.RequestFactoryServlet;
import com.tomagency.cyberlab.server.api.BubuApiServlet;
import com.tomagency.cyberlab.server.exports.BubuHandler;
import com.tomagency.cyberlab.server.exports.BubuHandlerImpl;
import com.tomagency.cyberlab.server.imports.TaopixFtpBackgroundScanner;
import com.tomagency.cyberlab.server.imports.TaopixFtpBackgroundScannerImpl;
import com.tomagency.cyberlab.server.request.BelegRequestService;
import com.tomagency.cyberlab.server.request.BelegRequestServiceImpl;
import com.tomagency.cyberlab.server.request.KontaktRequestService;
import com.tomagency.cyberlab.server.request.KontaktRequestServiceImpl;
import com.tomagency.cyberlab.server.request.MessageRequestService;
import com.tomagency.cyberlab.server.request.MessageRequestServiceImpl;
import com.tomagency.cyberlab.server.rpc.BelegServlet;
import com.tomagency.cyberlab.server.rpc.ScannerControlServlet;
import com.tomagency.cyberlab.server.rpc.UserServiceServlet;
import com.tomagency.cyberlab.server.util.LoggingUtil;
import com.tomagency.cyberlab.server.util.LoggingUtilImpl;
import com.tomagency.cyberlab.shared.rpc.ServletServicePfade;

import de.gammadata.persistence.*;

/**
 * Hilfsklasse um einige Abhängigkeiten, die nicht per GUICE direkt zur Verfügung gestellt werden können, zu erhalten
 * @author gfr
 *
 */
public class ConfigProviderFactory {
	/* Singelton */
	private static Injector injector;
	
	public static final String log4jFile = "/META-INF/log4j.properties";
//	public static final String persistenceUnitName = "cyberlab";
	
	
	public static PersistenceManager getPersistenceManager(){
		PersistenceManager pm = getInjector().getInstance(PersistenceManager.class);
		return pm;
	}
	
	public static CyberlabConfigProvider getCyberlabConfigProvider(){
		CyberlabConfigProvider obj = getInjector().getInstance(CyberlabConfigProvider.class);
		return obj;
	}
	
	public static BubuHandler getBubuHandler(){
		BubuHandler obj = getInjector().getInstance(BubuHandler.class);
		return obj;
	}
	
	public static TaopixFtpBackgroundScanner getTaopixFtpBackgroundScanner(){
		TaopixFtpBackgroundScanner obj = getInjector().getInstance(TaopixFtpBackgroundScanner.class);
		return obj;
	}
	
	public static LoggingUtil getLoggingUtil(){
		LoggingUtil logutil = getInjector().getInstance(LoggingUtil.class);
		return logutil;
	}
	

	
	public static Injector getInjector(){
		
		if (injector!=null){
			return injector;
		}

		  System.out.println(CyberlabGuiceServerConfigImpl.class.getName()+"getInjector() START -----------------------------");
		  System.out.println(CyberlabGuiceServerConfigImpl.class.getName()+"System Informationen");
		  
			
	      Properties pr = System.getProperties();
	        TreeSet propKeys = new TreeSet(pr.keySet());  // TreeSet sorts keys
	        for (Iterator it = propKeys.iterator(); it.hasNext(); ) {
	            String key = (String)it.next();
	            System.out.println("" + key + "=" + pr.get(key));
	        }
//		  Injector injector;
		  
		  //Log4j Konfiguration
	       
     try {
  	   ClassLoader cl=Thread.currentThread().getContextClassLoader();		
  	   URL url = cl.getResource(log4jFile);
				PropertyConfigurator.configure(url);
				System.out.println(CyberlabGuiceServerConfigImpl.class.getName()+"log4j konfiguriert");
			} catch (Exception e) {
				System.out.println(CyberlabGuiceServerConfigImpl.class.getName()+ " Fehler beim konfigurieren log4j, Pfad="+log4jFile);
				e.printStackTrace();
			} 
				
				
		try {
			injector = Guice.createInjector(Stage.DEVELOPMENT,new ServletModule()
			{
				@Override
				protected void configureServlets() {
					
				        
				        System.out.println(CyberlabGuiceServerConfigImpl.class.getName()+"Sytem Informationen");
//					System.out.println("configureServlets(): running on: "
//							   +System.getProperty("os.arch")
//							   +" - "+System.getProperty("os.name")
//							   +" - "+System.getProperty("os.version")
//							   +" Fileseparator= "+System.getProperty("file.separator")
//							   +" Pathseparator= "+System.getProperty("path.separator")
//							   +"\n"
//							   +"java.version");
					Logger logger = Logger.getLogger(CyberlabGuiceServerConfigImpl.class);
				

					
				       try {
				    	   
				    	   
				    	   //bindings füR DIE JEWEILIGE PLATTFORM ANPASSEN !!
				    	   
				    	   bind (LoggingUtil.class).to(LoggingUtilImpl.class).in(Singleton.class);
						
				    	   String osName= System.getProperty("os.name");
				    	   
			    	   		if (osName.matches(".*OS.*X.*")){
			    	   			logger.info("Running on "+osName+" - Configuring for OS X");
			    	    	    bind (FileSystemConfig.class).to(OsxFileSystemConfigImpl.class);

			    	   		}
				      
			    	   		else{
			    	   			//Ubuntu/Linux
			    	   			logger.info("Running on "+osName+" - Configuring for Linux Systems"); 
			    	   			bind (FileSystemConfig.class).to(LinuxFileSystemConfigImpl.class);
//			    	    	    bind (ReporttoolFileSystemConfig.class).to(ReporttooFileSystemConfigUbuntu.class);
//			    	    	    bind (EmailFileSystemConfig.class).to(ReporttooFileSystemConfigUbuntu.class);
			    	   		}
			    	   		
			    	   		bind (PersistenceManager.class).to(CyberlabPersistenceManagerImpl.class).in(Singleton.class);
			    	   		
			    	   		bind (AdressDAO.class).in(Scopes.SINGLETON);
			    	   		bind (KontaktDAO.class).in(Scopes.SINGLETON);
			    	   		bind (LandDAO.class).in(Scopes.SINGLETON);
			    	   		bind (BelegDAO.class).in(Scopes.SINGLETON);	
			    	   		bind (KommAdressenDAO.class).in(Scopes.SINGLETON);
			    	   		bind (MessageDAO.class).in(Scopes.SINGLETON);
			    	   		bind (ProduktDAO.class).in(Scopes.SINGLETON);
			    	   		
			    	   		bind (CyberlabConfigProvider.class).to(CyberlabConfigProviderImpl.class).in(Singleton.class);
			    	   		bind (BubuHandler.class).to(BubuHandlerImpl.class).in(Singleton.class);
			    	   		bind (TaopixFtpBackgroundScanner.class).to(TaopixFtpBackgroundScannerImpl.class);
			    	   		bind (BelegRequestService.class).to(BelegRequestServiceImpl.class).in(Singleton.class);
			    	   		bind (KontaktRequestService.class).to(KontaktRequestServiceImpl.class).in(Singleton.class);
			    	   		bind (MessageRequestService.class).to(MessageRequestServiceImpl.class).in(Singleton.class);
			    	   		
			    	   		
			    	   		
			    	   		
			    	   		//

			    	   		
//			    		    bind(ExceptionHandler.class).to(DefaultExceptionHandler.class);
//			    		    bind(ServiceLayerDecorator.class).to(InjectedServiceLayerDecorator.class);
//			    		    bind(InjectingServiceLocator.class);
				    	 
				    	   	
				   
							/*
							 * Hier werden die Request Pfade zu den Servlets zugeordnet
							 * entspricht dem servlet-mapping im web.xml
							 * com.google.gwt.requestfactory.server.RequestFactoryServlet
							 */
//			    	   		serve(ServletServicePfade.GWT_REQUEST).with(InjectedRequestFactoryServlet.class);
//			    	   		serve(ServletServicePfade.GWT_REQUEST).with(RequestFactoryServlet.class);

			    	   		serve(ServletServicePfade.UserServiceServlet).with(UserServiceServlet.class);
			    	   		serve(ServletServicePfade.ScannerServiceServlet).with(ScannerControlServlet.class);
			    	   		serve(ServletServicePfade.BelegServiceServlet).with(BelegServlet.class);
			    	   		serve(ServletServicePfade.BubuServiceServlet).with(BubuApiServlet.class);

//							   serve(ServletServicePfade.ResourceServiceServlet+"/*").with(de.reporttool.filemanager.server.servlets.ResourcesServlet.class);
//						       serve(ServletServicePfade.ServiceProviderServlet).with(de.reporttool.filemanager.server.servlets.ServiceProviderImpl.class);
//						       serve(ServletServicePfade.EmailServiceServlet).with(de.reporttool.filemanager.server.servlets.EmailServiceServlet.class);

			    	   		System.out.println(CyberlabGuiceServerConfigImpl.class.getName()+"getInjector() OK !!!!!!!!!!!");	
				       
				       } catch (Exception e) {
								System.out.println("configureServlets(): Fehler beim Erzeugen Klassen durch GUICE-Injector");
								e.printStackTrace();
							}
							 System.out.println(CyberlabGuiceServerConfigImpl.class.getName()+"getInjector() ENDE -----------------------------");
				     }
				
				}
			
			
			);
		} catch (Exception e) {
			Logger logger = Logger.getLogger(CyberlabGuiceServerConfigImpl.class);
			logger.error("configureServlets(): Fehler beim Erzeugen Klassen durch GUICE-Injector",e);
			return null;
		}
		  return injector;
		
	}

}
